/**
 * cluefollowup服务实现
 *
 * @author sxf
 * @email sxf02615@163.com
 * @date 2025/1/15
 */
package com.sxf.crm.service.impl;


import com.sxf.crm.dto.ClueFollowUpDTO;
import com.sxf.crm.dto.ClueFollowUpRequest;
import com.sxf.crm.entity.Clue;
import com.sxf.crm.entity.ClueFollowUp;
import com.sxf.crm.enums.ClueStatus;
import com.sxf.crm.repository.ClueFollowUpRepository;
import com.sxf.crm.repository.ClueRepository;
import com.sxf.crm.service.ClueFollowUpService;     
import com.sxf.crm.service.UserService;
import com.sxf.crm.utils.SecurityUtils;

import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class ClueFollowUpServiceImpl implements ClueFollowUpService {
    
    private final ClueFollowUpRepository clueFollowUpRepository;
    private final ClueRepository clueRepository;
    
    private final UserService userService;

    @Override
    public List<ClueFollowUpDTO> listByClueId(Long clueId) {
        List<ClueFollowUp> followUps = clueFollowUpRepository.findByClueIdOrderByFollowUpTimeDesc(clueId);
        return followUps.stream().map(this::convertToDTO).collect(Collectors.toList());
    }
    
    @Override
    @Transactional
    public ClueFollowUpDTO addFollowUp(Long clueId, ClueFollowUpRequest request,Long currentUserId) {
        // 验证线索是否存在
        Clue clue = clueRepository.findById(clueId)
                .orElseThrow(() -> new RuntimeException("线索不存在"));
        
        ClueFollowUp followUp = new ClueFollowUp();
        BeanUtils.copyProperties(request, followUp);
        followUp.setClueId(clueId);
        followUp.setCreateAt(System.currentTimeMillis());
        followUp.setCreateUserId(currentUserId);

        followUp.setUserId(request.getFollowUpUserId());
        
        followUp = clueFollowUpRepository.save(followUp);
        
        // 更新线索的最后跟进时间和下次跟进时间
        clue.setLastFollowUpTime(followUp.getFollowUpTime());
        if (followUp.getNextPlanTime() != null) {
            clue.setNextFollowUpTime(followUp.getNextPlanTime());
        }
        clue.setUpdateAt(System.currentTimeMillis());
        clue.setStatus(ClueStatus.FOLLOW_UP);
        clueRepository.save(clue);
        
        return convertToDTO(followUp);
    }
    
    @Override
    @Transactional
    public ClueFollowUpDTO updateFollowUp(Long id, ClueFollowUpRequest request) {
        ClueFollowUp followUp = clueFollowUpRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("跟进记录不存在"));
        
        BeanUtils.copyProperties(request, followUp, "id", "clueId", "userId", "createAt", "createUserId");
        followUp.setUpdateAt(System.currentTimeMillis());
        followUp.setUpdateUserId(SecurityUtils.getCurrentUserId());

        followUp = clueFollowUpRepository.save(followUp);
        return convertToDTO(followUp);
    }
    
    @Override
    @Transactional
    public void deleteFollowUp(Long id,Long currentUserId) {
        if (!clueFollowUpRepository.existsById(id)) {
            throw new RuntimeException("跟进记录不存在");
        }
        ClueFollowUp followUp = clueFollowUpRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("跟进记录不存在"));
        if (!followUp.getCreateUserId().equals(currentUserId)) {
            throw new RuntimeException("您没有权限删除此跟进记录");
        }
        
        clueFollowUpRepository.deleteById(id);
    }
    
    @Override
    public ClueFollowUpDTO getFollowUp(Long id) {
        ClueFollowUp followUp = clueFollowUpRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("跟进记录不存在"));
        return convertToDTO(followUp);
    }
    
    @Override
    public List<ClueFollowUpDTO> getUserFollowUps(Long userId) {
        List<ClueFollowUp> followUps = clueFollowUpRepository.findByUserId(userId);
        return followUps.stream().map(this::convertToDTO).collect(Collectors.toList());
    }
    
    @Override
    public void sendReminders() {
        LocalDateTime now = LocalDateTime.now();
        List<ClueFollowUp> reminders = clueFollowUpRepository.findRemindersToSend(now);
        
        // TODO: 实现提醒逻辑，如发送邮件、短信或系统通知
        for (ClueFollowUp reminder : reminders) {
            // 发送提醒的具体实现
            System.out.println("发送提醒：线索" + reminder.getClueId() + "需要跟进");
        }
    }
    
    private ClueFollowUpDTO convertToDTO(ClueFollowUp followUp) {
        ClueFollowUpDTO dto = new ClueFollowUpDTO();
        
        // 复制基本字段
        dto.setId(followUp.getId());
        dto.setClueId(followUp.getClueId());
        dto.setContent(followUp.getContent());
        dto.setRemind(followUp.getRemind());
        dto.setFollowUpUserId(followUp.getUserId());
        dto.setCreateUserId(followUp.getCreateUserId());
        
        // 处理枚举字段转换
        if (followUp.getMethod() != null) {
            dto.setMethod(followUp.getMethod().getLabel());
        }
        
        if (followUp.getRemindType() != null) {
            dto.setRemindType(followUp.getRemindType().getLabel());
        }
        
        // 处理时间字段转换 (Long -> LocalDateTime)
        if (followUp.getFollowUpTime() != null) {
            dto.setFollowUpTime(followUp.getFollowUpTime());
        }
        
        if (followUp.getNextPlanTime() != null) {
            dto.setNextPlanTime(followUp.getNextPlanTime());
        }
        
        if (followUp.getRemindTime() != null) {
            dto.setRemindTime(followUp.getRemindTime());
        }
        
        if (followUp.getCreateAt() != null) {
            dto.setCreateAt(followUp.getCreateAt());
        }
        
        if (followUp.getUserId() != null) {
            var user = userService.getUserById(followUp.getUserId());
            dto.setFollowUpUserName(user.getUsername()); 
        }

        if (followUp.getCreateUserId() != null) {
            var user = userService.getUserById(followUp.getCreateUserId());
            dto.setCreateUserName(user.getUsername()); 
        }
        
        return dto;
    }
} 